﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ListNetRanker;

namespace ListNetRankerConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Useage();
                return;
            }

            bool bTrainModel = false;
            foreach (string arg in args)
            {
                if (arg == "-train")
                {
                    bTrainModel = true;
                    break;
                }
                if (arg == "-?" || arg == "-h")
                {
                    Useage();
                    return;
                }
            }

            if (bTrainModel == true)
            {
                /*
             * 训练以及持久化
             */
                String input = "train.txt";
                String output = "msdata.listnet.module";
                int round = 4000;
                for (int i = 0; i < args.Length; )
                {
                    if (args[i].Equals("-i"))
                    {
                        input = args[i + 1];
                        i += 2;
                    }
                    else if (args[i].Equals("-o"))
                    {
                        output = args[i + 1];
                        i += 2;
                    }
                    else if (args[i].Equals("-t"))
                    {
                        round = int.Parse(args[i + 1]);
                        i += 2;
                    }
                    else
                    {
                        i++;
                    }
                }
                Parameters.setEpochnum(round);
                ListNetModule m = Trainer.train(input);
                m.write(output);

            }
            else
            {
                /*
                 * 从文件中读出模型，并用于测试
                 */
                String module = "msdata.listnet.module";
                String input = "test.txt";
                String output = "myRank.txt";
                for (int i = 0; i < args.Length; )
                {
                    if (args[i].Equals("-i"))
                    {
                        input = args[i + 1];
                        i += 2;
                    }
                    else if (args[i].Equals("-o"))
                    {
                        output = args[i + 1];
                        i += 2;
                    }
                    else if (args[i].Equals("-m"))
                    {
                        module = args[i + 1];
                        i += 2;
                    }
                    else
                    {
                        i++;
                    }
                }
                ListNetModule m = ListNetModule.CreateInstance(module);
                StreamReader reader = new StreamReader(input);
                StreamWriter writer = new StreamWriter(output);

                String line = null;
                List<IndexScore> list = new List<IndexScore>();
                int lastqid = -1;
 
                int index = 0;
                int[] sorted;
                while ((line = reader.ReadLine()) != null)
                {
                    Document doc = Document.Parse(line);
                    doc = m.GetNormalizer().normalize(doc);

                    if (doc.qid != lastqid)
                    {
                        lastqid = doc.qid;
                        if (list != null && list.Count != 0)
                        {
                            list.Sort();
                            sorted = new int[list.Count];
                            for (int i = 0; i < sorted.Length; i++)
                            {
                                sorted[list[i].index] = i + 1;
                            }
                            for (int i = 0; i < sorted.Length; i++)
                            {
                                if (i != sorted.Length - 1)
                                    writer.Write(sorted[i] + " ");
                                else
                                    writer.Write(sorted[i] + "");
                            }
                            writer.Write("\n");
                            list = new List<IndexScore>();
                            index = 0;
                        }
                    }
                    list.Add(new IndexScore(index++, m.GetRankScore(doc.features)));

                }

                list.Sort();
                sorted = new int[list.Count];
                for (int i = 0; i < sorted.Length; i++)
                {
                    sorted[list[i].index] = i + 1;
                }
                for (int i = 0; i < sorted.Length; i++)
                {
                    if (i != sorted.Length - 1)
                        writer.Write(sorted[i] + " ");
                    else
                        writer.Write(sorted[i] + "");
                }
                writer.Write("\n");
                writer.Close();
            }
        }

        private static void Useage()
        {
            Console.WriteLine("-train [option to train model]");
            Console.WriteLine("-test [option to test model]");
            Console.WriteLine("-i [input filename]");
            Console.WriteLine("-o [output filename]");
            Console.WriteLine("-t [total iteration number]");
        }
    }
}
